package com.pig4cloud.pig.sthcloud.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.sthcloud.clients.TaskOpenFeginClients;
import com.pig4cloud.pig.sthcloud.clients.TiandituReverseGeocodeClient;
import com.pig4cloud.pig.sthcloud.entity.GpggaData;
import com.pig4cloud.pig.sthcloud.entity.SthcloudPpkSloveTaskEntity;
import com.pig4cloud.pig.sthcloud.entity.TaskEntity;
import com.pig4cloud.pig.sthcloud.mapper.SthcloudPpkSloveTaskMapper;
import com.pig4cloud.pig.sthcloud.service.SthcloudPpkSloveTaskService;
import com.pig4cloud.pig.sthcloud.util.CoordinateConverter;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * sthcloud表
 *
 * @author pig
 * @date 2025-07-02 16:42:16
 */
@Service
public class SthcloudPpkSloveTaskServiceImpl extends ServiceImpl<SthcloudPpkSloveTaskMapper, SthcloudPpkSloveTaskEntity> implements SthcloudPpkSloveTaskService {

	// 基础保存路径 - 可根据需要配置化
	private static final String BASE_SAVE_PATH = "D:\\test\\source";
    @Resource
    private CoordinateConverter coordinateConverter;
    @Resource
    private SthcloudPpkSloveTaskMapper sthcloudPpkSloveTaskMapper;
	@Resource
	private ObjectMapper objectMapper;
	@Resource
	private TaskOpenFeginClients taskOpenFeginClients;
	@Resource
	private TiandituReverseGeocodeClient tiandituReverseGeocodeClient;

	@Override
    public R<List<GpggaData>> listGpggaDataById(Integer id) {
		SthcloudPpkSloveTaskEntity address = sthcloudPpkSloveTaskMapper.selectById(id);
		if (address == null || address.getWorkdir() == null) {
			return R.failed("任务地址或工作目录为空");
		}
		Path fullPath = Paths.get(address.getWorkdir(),"source", "gpgga_point.gga");
		File ggaFile = fullPath.toFile();
		if (!ggaFile.exists()) {
			return R.failed("gga文件未找到");
		}

		List<GpggaData> result = readAndProcessGgaFile(ggaFile);

		// 将List转换为Map结构
		Map<String, Object> responseMap = new LinkedHashMap<>();
		responseMap.put("code", 0);
		responseMap.put("msg", "解析结果");
		responseMap.put("data", result);

		// 保存处理后的数据到指定路径
		saveGpggaDataToPpk(responseMap, id, null);

		return R.ok(result);
    }

	@Override
	public R<List<GpggaData>> parseAndSaveGpggaFile(MultipartFile file) {
		if( file == null || file.isEmpty()){
			return R.failed("未传入文件");
		}

		String originalFilename = removeFileExtension(file.getOriginalFilename());

		List<GpggaData> result = new ArrayList<>();

		try (BufferedReader reader = new BufferedReader(new InputStreamReader(file.getInputStream()))) {
			result = parseGpggaLines(reader);
		} catch (IOException e) {

		}

		// 构建返回结果
		Map<String, Object> responseMap = new LinkedHashMap<>();
		responseMap.put("code", 0);
		responseMap.put("msg", "文件解析结果");
		responseMap.put("data", result);

		// 使用文件名生成唯一路径，并保存 .ppk 文件
		saveGpggaDataToPpk(responseMap, -1, originalFilename);

		return R.ok(result);
	}

	/**
	 * 读取并处理GGA文件
	 * @param ggaFile 目标文件
	 * @return 处理后的数据列表
	 */
	private List<GpggaData> readAndProcessGgaFile(File ggaFile){
		List<GpggaData> results;

		try (BufferedReader reader = new BufferedReader(new FileReader(ggaFile))) {
			results = parseGpggaLines(reader);
		} catch (IOException e) {
			return Collections.emptyList();
		}
		return results;
	}

	/**
	 * 通用的方法，从 BufferedReader 中读取每一行并解析 GPGGA 数据
	 */
	private List<GpggaData> parseGpggaLines(BufferedReader reader) {
		List<GpggaData> result = new ArrayList<>();
		String line;
		boolean firstLine = true;

		try {
			while ((line = reader.readLine()) != null) {
				if (firstLine) {
					// 跳过第一行日期
					firstLine = false;
					continue;
				}
				R<GpggaData> data = processGpggaLine(line);
				if (data.getCode() == 1) {
					return null;
				}
				result.add(data.getData());
			}
		} catch (IOException e) {
			return Collections.emptyList();
		}

		return result;
	}

	@Override
	public R<GpggaData> processGpggaLine(String line) {
		String[] parts = line.split(",");
		// 检查行是否符合格式
		if (parts.length < 15 || !"$GPGGA".equals(parts[0])) {
			return R.failed("数据格式错误");
		}

		GpggaData data = new GpggaData();
		data.setGpggaRawData(parts[0]);
		if(!parts[1].isEmpty()){
			data.setUtcTime(parts[1]);
		}
		// 处理纬度
		data.setDecimalLatitude(coordinateConverter.validateInputDegrees(parts[2],true));
		data.setLatitudeDirection(coordinateConverter.validateInputDirection(parts[3]));

		// 处理经度
		data.setDecimalLongitude(coordinateConverter.validateInputDegrees(parts[4],false));
		data.setLongitudeDirection(coordinateConverter.validateInputDirection(parts[5]));

		// 设置其他字段
		if(!parts[6].isEmpty()){
			data.setQualityIndicator(parts[6]);
		}
		if(!parts[7].isEmpty()){
			data.setSatelliteCount(parts[7]);
		}
		if(!parts[8].isEmpty()){
			data.setHdop(parts[8]);
		}
		if(!parts[9].isEmpty()){
			data.setAltitude(parts[9]);
		}
		if(!parts[10].isEmpty()){
			data.setAltitudeUnit(parts[10]);
		}
		if(!parts[11].isEmpty()){
			data.setGeoidalSeparation(parts[11]);
		}
		if(!parts[12].isEmpty()){
			data.setGeoidalSeparationUnit(parts[12]);
		}
		if(!parts[13].isEmpty()){
			data.setDgpsAge(parts[13]);
		}
		if(!parts[14].isEmpty()){
			data.setDgpsStationId(parts[14]);
		}
		return R.ok(data);
	}


	/**
	 * 移除文件名的后缀
	 * @param filename 完整文件名
	 * @return 不包含后缀的文件名
	 */
	private String removeFileExtension(String filename) {
		if (filename == null || filename.isEmpty()) {
			return filename;
		}

		// 找到最后一个点号的位置
		int lastDotIndex = filename.lastIndexOf('.');
		if (lastDotIndex == -1) {
			// 没有后缀的情况
			return filename;
		}

		// 返回点号之前的部分
		return filename.substring(0, lastDotIndex);
	}
	/**
	 * 将GGA数据以原始JSON格式保存到ppk文件中
	 * @param result 完整的响应数据(包含code,msg,data)
	 * @param taskId 任务ID(用于创建文件夹)
	 */
	private void saveGpggaDataToPpk(Map<String, Object> result, Integer taskId, String originalFilename) {
		Path taskDir;
		if (taskId != null && taskId > 0) {
			taskDir = Paths.get(BASE_SAVE_PATH, String.valueOf(taskId));
		} else {
			taskDir = Paths.get(BASE_SAVE_PATH, originalFilename);
		}
		try {
			Files.createDirectories(taskDir);
		} catch (IOException e) {
			return;
		}

		Path ppkFile = taskDir.resolve("gpgga.ppk");

		try (BufferedWriter writer = Files.newBufferedWriter(ppkFile)) {
			writer.write(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(result));
		} catch (IOException e) {
			return;
		}

		TaskEntity taskEntity = new TaskEntity();

		//通过逆编码获取地理信息
		Object dataObject = result.get("data");

		if(dataObject instanceof List && !((List<?>) dataObject).isEmpty()){
			List<?> dataList = (List<?>) dataObject;
			Object firstData = dataList.get(0);
			if(firstData instanceof GpggaData){
				GpggaData firstItem = (GpggaData) firstData;
				String decimalLongitude = firstItem.getDecimalLongitude();
				String decimalLatitude = firstItem.getDecimalLatitude();
				Double lng = Double.parseDouble(decimalLongitude);
				Double lat = Double.parseDouble(decimalLatitude);
				Map<String, String> reverseGeocode = tiandituReverseGeocodeClient.reverseGeocode(lat, lng);
				taskEntity.setProvince(reverseGeocode.get("province"));
				taskEntity.setCity(reverseGeocode.get("city"));
				taskEntity.setDistrict(reverseGeocode.get("district"));
//				System.out.println(reverseGeocode);
			}
		}

		if (taskId != null && taskId > 0) {
			SthcloudPpkSloveTaskEntity entity = sthcloudPpkSloveTaskMapper.selectById(taskId);
			if( entity != null){
				taskEntity.setId(taskId);
				taskEntity.setTitle(entity.getTitle());
				taskEntity.setCmccMileage(entity.getCmccMileage());
				taskEntity.setMessage(entity.getMessage());
				taskEntity.setCmccId(entity.getCmccId());
				taskEntity.setProcessStatus(entity.getProcessStatus());
				taskEntity.setFileType(entity.getFileType());
				taskEntity.setCmccLog(entity.getCmccLog());
			}
		} else {
			//将文件名作为文件的任务id
			Integer fileId = Integer.parseInt(originalFilename);
			taskEntity.setId(fileId);
			taskEntity.setCmccId(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")) + fileId);
		}

		taskEntity.setExecPpk(ppkFile.toAbsolutePath().toString().replace("\\", "/"));
		taskEntity.setCreateUser("admin");
		TaskEntity qury = new TaskEntity();

		if(taskId != null && taskId > 0){
			qury.setId(taskEntity.getId());
			saveOrUpdate(qury, taskEntity);
		}else {
			//将文件名作为文件的任务id
			Integer fileId = Integer.parseInt(originalFilename);
			qury.setId(fileId);
			saveOrUpdate(qury, taskEntity);

		}
	}
	private void saveOrUpdate (TaskEntity qury, TaskEntity taskEntity){
		R<List<TaskEntity>> resultList = taskOpenFeginClients.getDetails(qury);
		List<TaskEntity> existing = resultList.getData();
		if (existing != null && !existing.isEmpty()) {
			taskOpenFeginClients.updateById(taskEntity);
		} else {
			taskOpenFeginClients.save(taskEntity);
		}
	}
}
